#!/usr/bin/env python

"""
docstring
"""

__author__ = 'rx.wen218@gmail.com'
import time, logging
import pdb

class UpdatePostAction:
    """
    Enumerate update post action
    """
    ADD = 1
    UPDATE = 2
    DELETE = 3

def DefaultBeforeUpdatePostHandler(action, post):
    return True 

class SyncTask:
    
    def __init__(self, src_provider, dst_provider):
        self.logger = logging.getLogger(__name__)
        self.src_provider = src_provider
        self.dst_provider = dst_provider
        self.before_update_post_handler = DefaultBeforeUpdatePostHandler

    def __GetDiffPosts(self, src_posts, dst_posts, posts_to_add, posts_to_update):
        """
        filter
        """
        dst_posts_dict = {}
        for post in dst_posts:
            dst_posts_dict[post.title] = post
        for post in src_posts:
            if dst_posts_dict.has_key(post.title):
               if dst_posts_dict[post.title].content != post.content \
                   or dst_posts_dict[post.title].tags != post.tags:
                   dst_posts_dict[post.title].content = post.content
                   dst_posts_dict[post.title].tags = post.tags
                   posts_to_update.append(dst_posts_dict[post.title])
            else:
                posts_to_add.append(post)

    def SetBeforeUpdatePostHandler(self, handler = DefaultBeforeUpdatePostHandler):
        self.before_update_post_handler = handler

    def Run(self, start_date = None, end_date = None):
        posts_to_add = []
        posts_to_update = []
        src_posts = self.src_provider.GetPosts(start_date = start_date, end_date = end_date)
        time_format = "%Y-%m-%d %H:%M:%S"
        self.logger.info("got %d posts between %s and %s from source"%(len(src_posts), 
            start_date.strftime(time_format), end_date.strftime(time_format)))
        dst_posts = self.dst_provider.GetPosts(start_date = start_date, end_date = end_date)
        self.logger.info("got %d posts between %s and %s from detination"%(len(dst_posts),
            start_date.strftime(time_format), end_date.strftime(time_format)))
        self.__GetDiffPosts(src_posts, dst_posts, posts_to_add, posts_to_update)
        self.logger.info("%d posts to be added, %d posts to be updated"%(len(posts_to_add), len(posts_to_update)))

        total = len(posts_to_add) + len(posts_to_update)
        finished = 0
        # sleep a few seconds between each adding / updating in case we may be blocked by the blog host
        for post in posts_to_add:
            finished+=1
            if self.before_update_post_handler(UpdatePostAction.ADD, post):
                self.logger.info("[%d/%d] add post: [%s] %s"%(finished, total, post.create_date, post.title))
                self.dst_provider.AddPost(post)
        for post in posts_to_update:
            finished+=1
            if self.before_update_post_handler(UpdatePostAction.UPDATE, post):
                self.logger.info("[%d/%d] update post: [%s] %s"%(finished, total, post.create_date, post.title))
                self.dst_provider.UpdatePost(post)
